package entity

import (
	"context"
	"errors"
	"fmt"
	"src/zeus/dbservice"
	"src/zeus/global"
	"src/zeus/iserver"
	"src/zeus/logger"
	"src/zeus/msgdef"
	"src/zeus/msghandler"
	"src/zeus/serializer"
	"src/zeus/serverMgr"
	"src/zeus/threads"
	"src/zeus/timerwheel"
	"strconv"
	"sync"
	"sync/atomic"
	"time"
)

type iEntityCtrl interface {
	FireMsg(name string, content interface{})
	GetClientSess() iserver.ISess
	GetRawClientSess() iserver.ISess //不会过滤无效会话,需要自行处理;
	OnEntityCreated(entityID uint64, entityType string, UID uint64, spaceID uint64, protoType IEntityReal, entities iserver.IEntities, initParam interface{}, syncInit bool, fly bool)
	//主要是用来初始化匿名interface成员如IEntities
	OnPostEntityCreated()
	OnEntityDestroyed()
	IsDestroyed() bool
	MainLoop()
	GetDestroySigChan() <-chan bool
	//Loop时的时间
	GetNowTime() time.Time
	//设置Loop时的时间
	SetNowTime(n time.Time)
	//设置TICK的时间 只有系统协程可以对子协程做
	SetTickerNow(n time.Time)
	//获取TICK器
	GetTicker() <-chan time.Time
}

var _ iserver.IDelayCallHost = &Entities{}

// Entities entity的集合
type Entities struct {
	//上级实例
	owner iserver.IEntities

	msgHandler *msghandler.MsgHandler

	isMutilThread bool

	entityCnt int32

	entities       sync.Map        //所有Entity key=entityID, value=iserver.IEntity
	entitiesByType sync.Map        //所有Entity,Type分组 EntityID为Key key=entityType, value=sync.Map:(key=entityID, value=iserver.IEntity)
	entitiesByDBID sync.Map        //所有Entity,Type分组 DBID为Key     key=entityType, value=sync.Map:(key=DBID, value=iserver.IEntity)
	entitiesGroup  sync.Map        //key=groupID, value=sync.Map:(key=entityID, value=iserver.IEntity)
	entitiesChan   sync.Map        //拥有独立协程的Entity key=entityID, value=entity.iEntityCtrl && (iserver.IEntity)
	needRegType    map[uint8]uint8 //srVType 是否

	DelayCallHost
	thgo *threads.ThreadGo
}

// NewEntities 创建一个新的Entities
func NewEntities(isMutilThread bool, msgHandler *msghandler.MsgHandler, owner iserver.IEntities, delaySize int) *Entities {

	if msgHandler == nil {
		msgHandler = msghandler.NewMsgHandler()
	}
	result := &Entities{
		owner:      owner,
		msgHandler: msgHandler,
		// GlobalEvents: events.NewGlobalEventsInst(),

		isMutilThread: isMutilThread,

		needRegType: make(map[uint8]uint8),
		thgo:        threads.NewThreadGo(),
	}
	result.DelayCallHost.SetDelayCallHandle(NewDelayCallHandle(delaySize))
	return result
}

func (es *Entities) GetMsgHandler() iserver.IMsgHandler {
	return es.msgHandler
}

// Init 初始化
func (es *Entities) Init() {
	es.msgHandler.RegMsgProc(&EntitiesMsgProc{es.owner})
}

func (es *Entities) Recycle() {
	es.entities = sync.Map{}
	es.entitiesByDBID = sync.Map{}
	es.entitiesByType = sync.Map{}
	es.entitiesChan = sync.Map{}
	es.entitiesGroup = sync.Map{}
}

// Destroy 删除所有的实体
func (es *Entities) Destroy() {
	logger.Debug(logger.LogKey_Boot, "Entities.Destroy")

	es.entities.Range(
		func(k, v interface{}) bool {
			if err := es.DestroyEntity(k.(uint64)); err != nil {
				logger.Error(err)
			}
			return true
		})
	es.thgo.CloseWait()
	// es.entitiesByType = nil
	// es.entitiesByDBID = nil
	// es.entitiesGroup = nil
	// es.entities = nil
}

// SyncDestroy 删除所有Entity, 并等待所有Entity删除结束
func (es *Entities) SyncDestroy() {
	logger.Debug(logger.LogKey_Boot, "Entities.SyncDestroy")
	//通知销毁所有Entity
	es.entities.Range(
		func(k, v interface{}) bool {
			//logger.Debug(logger.LogKey_Boot, "--------------")
			//logger.Debugf(logger.LogKey_Boot, "Entity start destroy %T :%v", v, v)
			if err := es.DestroyEntity(k.(uint64)); err != nil {
				logger.Error(err)
			}
			//destroyedCheckers = append(destroyedCheckers, func() {
			//	for {
			//		if v.(iEntityState).IsDestroyed() {
			//			break
			//		}
			//
			//		time.Sleep(1 * time.Millisecond)
			//	}
			//})
			return true
		})

	//异步等待所有协程结束(会调用Calcel 触发ctx.Done() 事件的)
	es.thgo.CloseWait()
	logger.Debug(logger.LogKey_Boot, "SyncDestroy done")
}

// MainLoop 自己的逻辑线程
func (es *Entities) MainLoop() {

	//es.msgHandler.DoMsg()

	if !es.isMutilThread {
		es.entities.Range(func(k, v interface{}) bool {
			v.(iEntityCtrl).MainLoop()
			return true
		})
	} else {
		n := es.owner.(timerwheel.ITimer).GetTickTime()
		es.entitiesChan.Range(func(k, v interface{}) bool {
			v.(iEntityCtrl).SetTickerNow(n)
			return true
		})
	}
}

// Range 遍历所有Entity
func (es *Entities) Range(f func(k, v interface{}) bool) {
	es.entities.Range(f)
}
func (es *Entities) TravsalAllEntity(f func(iserver.IEntity)) {
	es.entities.Range(func(k, v interface{}) bool {
		ise := v.(iserver.IEntityStateGetter)
		if ise.GetEntityState() != iserver.Entity_State_Loop {
			return true
		}

		f(v.(iserver.IEntity))
		return true
	})
}

// CreateEntity 创建实体
func (es *Entities) CreateEntity(entityType string, entityID uint64, dbid uint64, spaceID uint64, initParam interface{}, syncInit bool, fly bool) (iserver.IEntity, error) {

	// logger.Debug(logger.LogKey_LoginFlow, "[Entities] CreateEntity 登录流程 entityType: ", entityType, " entityID: ", entityID, " dbid: ", dbid)

	_, ok := es.entities.Load(entityID)

	if ok {
		return nil, fmt.Errorf("EntityID existed")
	}

	ie := iserver.GetSrvInst().NewEntityByProtoType(entityType).(iEntityCtrl)

	if spaceID != 0 {
		_, ok := ie.(iserver.ISpaceEntity)
		if !ok {
			return nil, fmt.Errorf("The entity must is a space entity")
		}
	}

	ie.OnEntityCreated(entityID, entityType, dbid, spaceID, ie.(IEntityReal), es.owner, initParam, syncInit, fly)
	es.addEntity(entityID, ie.(iserver.IEntity))
	var delayCallHandle iserver.IDelayCallHandle
	msgh := ie.(msghandler.IMsgHand)

	if es.isMutilThread {
		destroySig := ie.GetDestroySigChan()
		delayCallHost, ok := ie.(iserver.IDelayCallHost)
		if ok {
			delayCallHandle = NewDelayCallHandle(10)
			delayCallHost.SetDelayCallHandle(delayCallHandle)
		}
		es.thgo.Go(func(ctx context.Context) {
			if destroySig == nil {
				return
			}
			ticker := ie.GetTicker()
			es.entitiesChan.Store(entityID, ie)
			defer func() {
				es.entitiesChan.CompareAndDelete(entityID, ie)
			}()
			//如果Loop的时间 大于100毫秒，那每次有消息来的时候，就主动走一下MainLoop
			// 主要用于Lobby的逻辑
			msgloop := iserver.GetSrvInst().GetFrameDeltaTime() >= time.Millisecond*100
			for {
				select {
				case <-ctx.Done():
					{
						thisEntity := ie.(iserver.IEntity)

						istate := ie.(iserver.IEntityStateGetter)
						switch istate.GetEntityState() {
						case iserver.Entity_State_Init, iserver.Entity_State_Suspend:
							return
						case iserver.Entity_State_Loop:
							ie.OnEntityDestroyed()
							ie.(iEntityState).OnDestroy()
							istate.SetEntityState(iserver.Entity_State_InValid)
						}
						logger.Debugf(logger.LogKey_Entity, "  CreateEntity.Destroyed ctx.Done() %T %d,%d,%v", ie, thisEntity.GetID(), thisEntity.GetDBID(), thisEntity.GetType())
						ctx = context.Background() //避免后续再次触发 ctx.Done 覆盖ctx变量.
						//return //设置销毁状态后,再走 destroySig; 这里先不调用return, 等待循环一次,触发其他消息.
					}
				case <-destroySig:
					thisEntity := ie.(iserver.IEntity)
					logger.Debugf(logger.LogKey_Entity, "->Recv destroySig %T %v,%v,%v %v", ie,
						thisEntity.GetID(), thisEntity.GetDBID(), thisEntity.GetType(), thisEntity.String())
					return
				case <-msgh.GetCallChan():
					msgh.DoMsg()
					if msgloop {
						ie.MainLoop()
					}
				case n := <-ticker:
					ie.SetNowTime(n)
					ie.MainLoop()
				}
			}
		})
	}

	atomic.AddInt32(&es.entityCnt, 1)
	return ie.(iserver.IEntity), nil
}

// DestroyEntityByDBID 删除 Entity
func (es *Entities) DestroyEntityByDBID(entityType string, dbID uint64) error {
	e := es.GetEntityByDBID(entityType, dbID)
	if e == nil {
		return fmt.Errorf("Entity not existed")
	}

	return es.owner.DestroyEntity(e.GetID())
}

// DestroyEntity 删除Entity
func (es *Entities) DestroyEntity(entityID uint64) error {
	e, ok := es.entities.Load(entityID)
	if !ok {
		return fmt.Errorf("Entity not existed")
	}
	entity := e.(iserver.IEntity)
	logger.Debugf(logger.LogKey_Entity, "DestroyEntity entityID:%d %T ==> %s ", entityID, entity, entity)

	if es.GetTypeIsInRegMap(iserver.GetSrvInst().GetSrvType()) {
		es.UnRegEntityGroup(strconv.FormatUint(iserver.GetSrvInst().GetSrvID(), 10), entity)
	}
	es.delEntity(entity)
	//es.thgo.Wg.Add(1)
	es.CallDelay(func() {
		logger.Debug(logger.LogKey_Entity, "Entities -> DestroyEntity callDelay doReal destroy done1", entity.GetID(), entity.GetType(), entity.GetDBID())
		entity.(iEntityCtrl).OnEntityDestroyed()
		if !es.isMutilThread {
			entity.(iEntityState).OnDestroy()
		}
		//es.thgo.Wg.Done()
	})
	atomic.AddInt32(&es.entityCnt, -1)

	return nil
}

// GetEntity 获取Entity
func (es *Entities) GetEntity(entityID uint64) iserver.IEntity {
	if ie, ok := es.entities.Load(entityID); ok {
		return ie.(iserver.IEntity)
	}
	return nil
}

// GetEntityByDBID 获取Entity
func (es *Entities) GetEntityByDBID(entityType string, dbid uint64) iserver.IEntity {
	if it, ok := es.entitiesByDBID.Load(entityType); ok {

		if id, ok := it.(*sync.Map).Load(dbid); ok {
			return id.(iserver.IEntity)
		}
	}
	return nil
}

// TravsalEntity 遍历某一类型的entity
func (es *Entities) TravsalEntity(entityType string, f func(iserver.IEntity)) {
	if it, ok := es.entitiesByType.Load(entityType); ok {
		it.(*sync.Map).Range(func(k, v interface{}) bool {
			ise := v.(iserver.IEntityStateGetter)
			if ise.GetEntityState() != iserver.Entity_State_Loop {
				return true
			}

			f(v.(iserver.IEntity))
			return true
		})
	}
}

// TravsalEntity 遍历某一组的entity
func (es *Entities) TravsalEntityByGroup(entityGroup string, f func(iserver.IEntity)) {
	if it, ok := es.entitiesGroup.Load(entityGroup); ok {
		it.(*sync.Map).Range(func(k, v interface{}) bool {
			ise := v.(iserver.IEntityStateGetter)
			if ise.GetEntityState() != iserver.Entity_State_Loop {
				return true
			}

			f(v.(iserver.IEntity))
			return true
		})
	}
}

// addEntity  增加entity
func (es *Entities) addEntity(entityID uint64, e iserver.IEntity) {
	// logger.Debug("Entities addEntity entityID ", entityID)
	es.entities.Store(entityID, e)

	if e.GetDBID() != 0 {
		var t *sync.Map
		if it, ok := es.entitiesByDBID.Load(e.GetType()); ok {
			t = it.(*sync.Map)
		} else {
			t = &sync.Map{}
			if tmp, loaded := es.entitiesByDBID.LoadOrStore(e.GetType(), t); loaded {
				t = tmp.(*sync.Map)
			}
		}

		t.Store(e.GetDBID(), e)
	}

	var t *sync.Map
	if it, ok := es.entitiesByType.Load(e.GetType()); ok {
		t = it.(*sync.Map)
	} else {
		t = &sync.Map{}
		if tmp, loaded := es.entitiesByType.LoadOrStore(e.GetType(), t); loaded {
			t = tmp.(*sync.Map)
		}
	}

	t.Store(e.GetID(), e)
}

// delEntity 删除entity
func (es *Entities) delEntity(e iserver.IEntity) {

	es.entities.Delete(e.GetID())

	if e.GetDBID() != 0 {
		if it, ok := es.entitiesByDBID.Load(e.GetType()); ok {
			it.(*sync.Map).Delete(e.GetDBID())
		}
	}

	if it, ok := es.entitiesByType.Load(e.GetType()); ok {
		it.(*sync.Map).Delete(e.GetID())
	}

	es.delEntityGroup(e)
}

// RegEntityGroup  注册entityGroup
func (es *Entities) RegEntityGroup(group string, e iserver.IEntity) {

	var t *sync.Map
	if it, ok := es.entitiesGroup.Load(group); ok {
		t = it.(*sync.Map)
	} else {
		t = &sync.Map{}
		es.entitiesGroup.Store(group, t)
	}

	t.Store(e.GetID(), e)
	e.AddGroup(group)
}

// UnRegEntityGroup  注销entityGroup
func (es *Entities) UnRegEntityGroup(group string, e iserver.IEntity) {

	if it, ok := es.entitiesGroup.Load(group); ok {
		t := it.(*sync.Map)
		t.Delete(e.GetID())
		e.DelGroup(group)
	}

}

// UnRegEntityGroup  删除所有entityGroup
func (es *Entities) delEntityGroup(e iserver.IEntity) {

	e.GetGroups().(*sync.Map).Range(func(key, val interface{}) bool {
		if it, ok := es.entitiesGroup.Load(key); ok {
			t := it.(*sync.Map)
			t.Delete(e.GetID())
		}
		return true
	})
}

// EntityCount 返回实体数
// 所有Entity的数量,如需获取某个类型的Entity数量，请使用 Entities.TravsalEntity(),或者自行统计
func (es *Entities) EntityCount() int32 {
	return atomic.LoadInt32(&es.entityCnt)
	// return int(es.entityCnt)
}

// CreateEntityAll 创建实体的所有部分 UNUSED 流程不容易控制, 暂时不使用
func (es *Entities) CreateEntityAll(entityType string, dbid uint64, initParam interface{}, syncInit bool) (iserver.IEntity, error) {

	var entityID uint64
	entityID = iserver.GetSrvInst().FetchTempID()

	// 理论上tempID不可能重复
	/*
		if dbservice.EntitySrvUtil(entityID).IsExist() {
			return nil, fmt.Errorf("Entity existed")
		}
	*/

	srvList, _ := global.GetGlobalInst().GetGlobalIntSlice("EntitySrvTypes:" + entityType)
	// srvList, err := dbservice.EntityTypeUtil(entityType).GetSrvType()
	// if err != nil {
	// 	es.DestroyEntity(e.GetID())
	// 	return nil, err
	// }

	srvIDList := make([]uint64, 0, len(srvList))
	for _, v := range srvList {
		srvType := uint8(v)
		if srvType == iserver.GetSrvInst().GetSrvType() {
			continue
		}
		if !iserver.GetSrvInst().IsCanConnectBySrvType(iserver.GetSrvInst().GetGroupId(), srvType) {
			//表示没有本服务器没有连接目标服务器
			continue
		}
		srvID, err := iserver.GetSrvInst().GetSrvIDBySrvType(srvType)
		if err != nil {
			logger.Error(err)
			return nil, fmt.Errorf("CreateEntityAll GetSrvIDBySrvType [%d] is not exist .", srvType)
		}
		if !iserver.GetSrvInst().IsSessExist(srvID) {
			return nil, fmt.Errorf("CreateEntityAll srvID[%d] is not exist .", srvID)
		}
		srvIDList = append(srvIDList, srvID)
	}

	e, err := es.owner.CreateEntity(entityType, entityID, dbid, 0, initParam, syncInit, false)
	if err != nil {
		return nil, err
	}

	for _, v := range srvIDList {
		msg := &msgdef.CreateEntityReq{
			EntityType: entityType,
			EntityID:   entityID,
			SpaceID:    0,
			InitParam:  serializer.Serialize(initParam),
			DBID:       dbid,
			SrcSrvType: iserver.GetSrvInst().GetSrvType(),
			SrcSrvID:   iserver.GetSrvInst().GetSrvID(),
			CallbackID: 0,
		}

		if err := iserver.GetSrvInst().PostMsgToSpace(v, 0, msg); err != nil {
			logger.Error(err)
		}
	}
	return e, nil
}

// DestroyEntityAll 销毁实体的所有部分
func (es *Entities) DestroyEntityAll(entityID uint64) error {

	var srvInfos []*dbservice.EntitySrvInfo
	var err error

	e := es.GetEntity(entityID)
	if e == nil {
		srvInfos, err = dbservice.EntitySrvUtil(entityID).GetSrvIDs()
		if err != nil {
			logger.Error("Get entity srv info failed ", err)
			return err
		}
	} else {
		srvInfos = e.GetSrvIDS()
	}

	// srvInfos, err := dbservice.EntitySrvUtil(entityID).GetSrvIDs()
	// if err != nil {
	// 	log.Error("Get entity srv info failed ", err)
	// 	return err
	// }
	for _, srvInfo := range srvInfos {
		if srvInfo.SrvID == iserver.GetSrvInst().GetSrvID() {
			continue
		}
		//给Gateway和给Client逻辑是一样的
		if srvInfo.Stype == iserver.ServerTypeClient {
			continue
		}
		msg := &msgdef.DestroyEntityReq{
			EntityID:   entityID,
			SrcSrvType: iserver.GetSrvInst().GetSrvType(),
			SrcSrvID:   iserver.GetSrvInst().GetSrvID(),
			CallbackID: 0,
			SpaceID:    srvInfo.SpaceID,
			TarSrvID:   0,
		}

		if err := iserver.GetSrvInst().PostMsgToSpace(srvInfo.SrvID, srvInfo.SpaceID, msg); err != nil {
			logger.Error(err)
		}
	}

	return es.owner.DestroyEntity(entityID)
}

// MigrateEntity 把实体从一个服务器迁移到另一个服务器上（仅针对同一类型的服务器）
func (es *Entities) MigrateEntity(entityID uint64, tarType uint8, tarSrvID uint64, tarSpaceID uint64) (bool, error) {

	var err error
	var msg msgdef.IMsg
	e := es.GetEntity(entityID)
	if e == nil {
		logger.Error("Get entity failed by entityID", entityID)
		return false, errors.New("Get entity failed")
	}
	srcSrvID, srcSpaceID, err := e.GetEntitySrvID(tarType)
	if err != nil {
		return false, err
	}
	if srcSrvID == tarSrvID {
		return false, errors.New("srcSrvID is equal to tarSrvID ")
	}
	if list, err := serverMgr.GetServerMgr().GetServerListByType(iserver.GetSrvInst().GetGroupId(), tarType); err == nil {
		for _, va := range list {
			if va.ServerID == tarSrvID {

				// 判断是否是space里的对象
				if tarSpaceID == 0 {
					// 找到目标ID，先删除src里的entity
					msg = &msgdef.DestroyEntityReq{
						EntityID:   e.GetID(),
						SrcSrvType: iserver.GetSrvInst().GetSrvType(),
						SrcSrvID:   iserver.GetSrvInst().GetSrvID(),
						CallbackID: 0,
						SpaceID:    srcSpaceID,
						TarSrvID:   tarSrvID, // 删除完成后，在根据ID在新服务器上创建entity
					}

					if err := iserver.GetSrvInst().PostMsgToSpace(srcSrvID, srcSpaceID, msg); err != nil {
						logger.Error(err)
						return false, err
					}

				} else {
					/*
					   这块代码暂时不会使用到
					*/

					// 检查负载，这里后面要考虑是否太过频繁，是否可以改成定时检查
					// if full, err := dbservice.SpaceUtil(tarSpaceID).CheckIsFull(); err == nil && !full {
					// 切换在不同space里的对象，应该不会失败
					// e.LeaveSpaceByID(srcSpaceID)
					// e.EnterSpace(tarSpaceID)
					// }
				}
				return true, nil

			}
		}
	}

	return false, errors.New("can't MigrateEntity ")
}

// 给指定服务器类型发创建ntt对象的消息
func (es *Entities) CreateEntityByServerType(srvType uint8, e iserver.IEntity) (result bool, err error) {
	if !iserver.GetSrvInst().IsCanConnectBySrvType(iserver.GetSrvInst().GetGroupId(), srvType) {
		//表示没有本服务器没有连接目标服务器
		return false, fmt.Errorf("CreateEntityByServerType IsCanConnectBySrvType [%d] is not exist .", srvType)
	}
	srvID, err := iserver.GetSrvInst().GetSrvIDBySrvType(srvType)
	if err != nil {
		logger.Error(err)
		return false, fmt.Errorf("CreateEntityByServerType GetSrvIDBySrvType [%d] is not exist .", srvType)
	}
	if !iserver.GetSrvInst().IsSessExist(srvID) {
		return false, fmt.Errorf("CreateEntityByServerType srvID[%d] is not exist .", srvID)
	}
	msg := &msgdef.CreateEntityReq{
		EntityType: e.GetType(),
		EntityID:   e.GetID(),
		SpaceID:    0,
		InitParam:  serializer.Serialize(e.GetInitParam()),
		DBID:       e.GetDBID(),
		SrcSrvType: iserver.GetSrvInst().GetSrvType(),
		SrcSrvID:   iserver.GetSrvInst().GetSrvID(),
		CallbackID: 0,
	}

	if err := iserver.GetSrvInst().PostMsgToSpace(srvID, 0, msg); err != nil {
		logger.Error(err)
	}
	return true, nil
}

// // MigrateEntityForSpace 把实体从一个空间迁移到另一个空间上
// func (es *Entities) MigrateEntityForSpace(entityID uint64, srcSpaceID uint64, tarSpaceID uint64) (bool, error) {

// 	var err error
// 	var msg msgdef.IMsg
// 	e := es.GetEntity(entityID)
// 	if e == nil {
// 		log.Error("Get entity failed by entityID", entityID)
// 		return false, errors.New("Get entity failed")
// 	}
// 	e.LeaveSpaceByID(srcSpaceID)

// 	if list, err := serverMgr.GetServerMgr().GetServerListByType(tarType); err == nil {
// 		for _, va := range list {
// 			if va.ServerID == tarSrvID {

// 				// 找到目标ID，先删除src里的entity
// 				msg = &msgdef.DestroyEntityReq{
// 					EntityID:   e.GetID(),
// 					SrcSrvType: iserver.GetSrvInst().GetSrvType(),
// 					SrcSrvID:   iserver.GetSrvInst().GetSrvID(),
// 					CallbackID: 0,
// 					SpaceID:    srcSpaceID,
// 					TarSrvID:   tarSrvID, // 删除完成后，在根据ID在新服务器上创建entity
// 				}

// 				if err := iserver.GetSrvInst().PostMsgToSpace(srcSrvID, srcSpaceID, msg); err != nil {
// 					log.Error(err)
// 				}

// 				return true, nil
// 			}
// 		}
// 	}

// 	return false, errors.New("can't MigrateEntity ")
// }

// AddNeedRegType 增加需要注册group的entitytype
func (es *Entities) AddNeedRegType(srvType uint8) {
	es.needRegType[srvType] = srvType
}

// GetTypeIsInRegMap 判断entitytype是否在注册表里
func (es *Entities) GetTypeIsInRegMap(srvType uint8) bool {
	_, ok := es.needRegType[srvType]
	return ok
}

func (es *Entities) GetThreadGo() *threads.ThreadGo {
	return es.thgo
}
